home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 February / EnigmA AMIGA RUN 15 (1997)(G.R. Edizioni)(IT)[!][issue 1997-02][PLANET CD V].iso / enigma / earcd / sviluppo / svilupp2 / hw2sgfx2.lha / How2UseGfxV39 / SuperScroll.c < prev    next >
C/C++ Source or Header  |  1996-11-30  |  32KB  |  823 lines

  1. /*
  2.     File: ball.c
  3.  
  4.     Description: This is a short demo code that shows how we could
  5.                  handle OS3.x features to use fast blitter operation
  6.                  that are compatible with graphics boards. Images,
  7.                  3 balls, red, green and blue, will be remaped to the
  8.                  current colortable useing ObtainBestPen().
  9.                  Also the images will be converted to a friend format of
  10.                  the window they are drawn into. This means it _could_
  11.                  also be in chunky mode then, e.g. if used on a SD64 with
  12.                  an EGS driver, this images are chunky with a memory area
  13.                  located on the gfx board ! (I do not know if other board
  14.                  driver do support allocating display memory).
  15.                  All images are drawn transparent, check out masking and
  16.                  miniterms. This demo should run in all colormodes, though
  17.                  I haven't tryed true color cyber modes yet - do not know
  18.                  if we get 24 bit images then (but I think we will).
  19.  
  20.                  There is still one problem, the biggest one games coders
  21.                  will say. It does not double buffer. This is not possible
  22.                  with the method I use herein. So, yes, there is a problem
  23.                  with real smooth image movements...
  24.  
  25.                  I just wanted to show, that you can use OS3 to use effecient
  26.                  methods of image handling, without worring of the destination
  27.                  bitmap format ! This code generates the optimal bitmap format
  28.                  for the images by itself - see the BMF_FRIEND flag !
  29.                  This is important for me, since I want to write my own emulation.
  30.                  
  31.                  I know, this code is not the best you can get. There is some
  32.                  space to make it better. One could try to use custom (public:)
  33.                  screens, double buffering, background images etc. If you like
  34.                  go ahead and try what's possible.
  35.  
  36.                  I hope you enjoy it :)
  37.  
  38.     Author: Jürgen Schober
  39.             Muchargasse 35/1/4
  40.             A-8010 Graz
  41.             e-mail: jschober@campusart.com
  42.  
  43.     Date: 23.11.1996 (96/23/11)
  44.  
  45. */
  46.  
  47. // we use a public screen
  48.  
  49. #define PUBLIC_SCREEN
  50.  
  51. #include <stdio.h>
  52. #include <stdlib.h>
  53.  
  54. #include <clib/exec_protos.h>
  55. #include <clib/intuition_protos.h>
  56. #include <clib/graphics_protos.h>
  57. #include <clib/cybergraphics_protos.h>
  58.  
  59. #include <pragmas/exec_pragmas.h>
  60. #include <pragmas/intuition_pragmas.h>
  61. #include <pragmas/graphics_pragmas.h>
  62. #include <pragmas/cybergraphics_pragmas.h>
  63.  
  64. #include <exec/types.h>
  65. #include <intuition/intuition.h>
  66. #include <intuition/intuitionbase.h>
  67. #include <cybergraphics/cybergraphics.h>
  68.  
  69. #include <graphics/gfx.h>
  70.  
  71. // my images 
  72. // they where drawn using a 24 bit package, dithered to 256 colors and
  73. // saved to c source by PPaint 6.4 (and modified by me)
  74.  
  75. #include "GreenBall.h"
  76. #include "BallMaske.h"
  77. #include "Spectrum.h"
  78.  
  79. #define BG_WIDTH 640
  80. #define BG_HEIGHT 512
  81. #define BG_DEPTH 8
  82. #define BG_PLANESIZE 40960
  83. #define BG_PLANEWORDSIZE 20480
  84.  
  85. extern ULONG ScrollGroundPaletteRGB32[];
  86. extern UWORD ScrollGroundData[];
  87.  
  88. // Convert it:
  89.  
  90. #ifndef __SASC
  91.     #define __asm
  92. #endif
  93.  
  94. extern void __asm CopyPlane2Chunky(register __a2 APTR planes,register __a3 APTR chunky,
  95.                                    register __d6 WORD depth,register __d7 long BMSize);
  96.  
  97. struct Library *GfxBase = NULL;
  98. struct IntuitionBase *IntuitionBase = NULL;
  99. struct Window *win = NULL;
  100. struct Screen *screen = NULL;
  101. struct ColorMap *cm = NULL;
  102. struct RastPort *rp = NULL;
  103.  
  104. struct BitMap *GreenBall = NULL,*MaskBall = NULL ;
  105. struct BitMap *SuperBackGround = NULL;
  106. int x, y, gx, gy;
  107. int dx,dy, dgx, dgy;
  108. int x_old, y_old, gx_old, gy_old;
  109.  
  110. UBYTE bgpens[256],ballpens[256],pen;
  111. long background;
  112. int cycle = 0;
  113.  
  114. int BitMapDepth;    // for TrueColor Modes
  115. BOOL IsGfxBoard = FALSE;
  116. BOOL verbose = FALSE;
  117.  
  118.  
  119. #define PLANESIZE    BG_PLANESIZE
  120. #define IMAGE_WIDTH  BG_WIDTH
  121. #define IMAGE_HEIGHT BG_HEIGHT
  122. #define IMAGE_DEPTH  BG_DEPTH   // 8 planes
  123.  
  124. #define VISIBLE_WIDTH 320
  125. #define VISIBLE_HEIGHT 256
  126.  
  127. // ----------------------------------------------------------------------
  128. // Basic Exit Code
  129. // ----------------------------------------------------------------------
  130. void CleanUp()
  131. {
  132.     int i;
  133.  
  134.     // ------------------------------------------------------------------
  135.     // Free the pens again
  136.     // ------------------------------------------------------------------
  137.  
  138.     if (cm)
  139.     {
  140.         for (i = 0; i < 256 ; i++)
  141.         {
  142.            ReleasePen(cm,bgpens[i]);
  143.            ReleasePen(cm,ballpens[i]);
  144.         }
  145.     }
  146.  
  147.     // ------------------------------------------------------------------
  148.     // now we want to free the bitmaps again
  149.     // ------------------------------------------------------------------
  150.  
  151.     WaitBlit();
  152.  
  153.     if (GreenBall) FreeBitMap(GreenBall);
  154.     if (MaskBall)  FreeBitMap(MaskBall);
  155.  
  156.  
  157.     if (win)    CloseWindow(win);
  158. #ifdef PUBLIC_SCREEN
  159.     if (screen) UnlockPubScreen(NULL,screen);
  160. #else
  161.     if (screen) CloseScreen(screen);
  162. #endif
  163.  
  164.     // ------------------------------------------------------------------
  165.     // and don't forget to close the libraries !
  166.     // ------------------------------------------------------------------
  167.  
  168.     if (GfxBase) CloseLibrary(GfxBase);
  169.     if (IntuitionBase) CloseLibrary((struct Library*)IntuitionBase);
  170.  
  171.     exit(0);
  172. }
  173.  
  174. // ----------------------------------------------------------------------
  175. // As We have Shared Pens, We have to allocate Them Here
  176. // ----------------------------------------------------------------------
  177. void AllocateColors()
  178. {
  179.     int i,idx;
  180.  
  181.     // ------------------------------------------------------------------
  182.     // Init the Background Color
  183.     // ------------------------------------------------------------------
  184.  
  185.     if (!cm) CleanUp();
  186.  
  187.     if (verbose) { printf("Obtaining pens...\n\tPen "); fflush(stdout); }
  188.  
  189.     // ------------------------------------------------------------------
  190.     // here I try to get as many colors of my table in the windows colormap
  191.     // ------------------------------------------------------------------
  192.  
  193.     idx = 0;
  194.     for (i = 0; i < 256; i++)
  195.     {
  196.         bgpens[i] = ObtainBestPen(cm,
  197.                                 ScrollGroundPaletteRGB32[idx++],
  198.                                 ScrollGroundPaletteRGB32[idx++],
  199.                                 ScrollGroundPaletteRGB32[idx++],
  200.                                 OBP_Precision,PRECISION_EXACT,
  201.                                 TAG_DONE);
  202.  
  203.         if (verbose) { printf("%d = %d ",i,bgpens[i]); fflush(stdout); }
  204.  
  205.     }
  206.  
  207.     // ------------------------------------------------------------------
  208.     // after I have my image colors I also need some for my ball
  209.     // ------------------------------------------------------------------
  210.  
  211.     idx = 0;
  212.     for (i = 0; i < 256; i++)
  213.     {
  214.         ballpens[i] = ObtainBestPen(cm,
  215.                                 BallPaletteRGB32[idx++],
  216.                                 BallPaletteRGB32[idx++],
  217.                                 BallPaletteRGB32[idx++],
  218.                                 OBP_Precision,PRECISION_EXACT,
  219.                                 TAG_DONE);
  220.  
  221.         if (verbose) { printf("%d = %d ",i,bgpens[i]); fflush(stdout); }
  222.  
  223.     }
  224.     if (verbose) { puts("done."); fflush(stdout); }
  225.  
  226. }
  227.  
  228. // ----------------------------------------------------------------------
  229. // Images have to be brought into a usable format
  230. // ----------------------------------------------------------------------
  231. void CreateBackGround(struct BitMap *bm)
  232. {
  233.     int i;
  234.     ULONG pixels;
  235.     UBYTE *buffer;
  236.     UBYTE *ChunkyData;
  237.     UBYTE *Planes[8];
  238.     struct RastPort tmpRastPort,tmpRastPort2;
  239.  
  240.  
  241.     // ------------------------------------------------------------------
  242.     // This is some support code if we run on a TrueColor Cyber Screen
  243.     // in this case the Color Cycling has to be done in a different way
  244.     // ------------------------------------------------------------------
  245.  
  246.     struct Library *CyberGfxBase; 
  247.  
  248.     if (CyberGfxBase = OpenLibrary("cybergraphics.library",40))
  249.     {
  250.         if (GetCyberMapAttr(rp->BitMap,CYBRMATTR_ISCYBERGFX))
  251.         {
  252.             BitMapDepth = GetCyberMapAttr(rp->BitMap,CYBRMATTR_DEPTH);
  253.         }
  254.         CloseLibrary(CyberGfxBase);
  255.     }
  256.  
  257.     // ------------------------------------------------------------------
  258.     // I support v39 now, so I need another RastPort for the WritePixelArray8()
  259.     // ------------------------------------------------------------------
  260.  
  261.     CopyMem(rp,&tmpRastPort2,sizeof(struct RastPort));
  262.     tmpRastPort2.Layer = NULL;
  263.     tmpRastPort2.BitMap = AllocBitMap(BG_WIDTH,1,BG_DEPTH,0,NULL);
  264.  
  265.     // ------------------------------------------------------------------
  266.     // I also need my images in an array for the next loop, see there
  267.     // ------------------------------------------------------------------
  268.  
  269.     // ------------------------------------------------------------------
  270.     // we need a chunky buffer, we need it only once because of the same size
  271.     // this chunky buffer is needed because I want to remap the images to 
  272.     // the available colors. This is really easy if you have 8 bit chunky sources
  273.     // ------------------------------------------------------------------
  274.  
  275.     if (!(ChunkyData = AllocVec(BG_WIDTH * BG_HEIGHT, 0))) 
  276.     {
  277.         CleanUp();
  278.     }
  279.     
  280.     // ------------------------------------------------------------------
  281.     // this loop converts my 3 plane sources to chunky images and
  282.     // remaps them to the colors allocated above
  283.     // ------------------------------------------------------------------
  284.  
  285.     if (verbose) { printf("Converting plane to chunky ..."); fflush(stdout); }
  286.  
  287.     // -------------------------------------------------------------------
  288.     // my own convert routine wants the planes in an array of planepointers
  289.     // -------------------------------------------------------------------
  290.  
  291.     Planes[0] = (PLANEPTR)&ScrollGroundData[0*BG_PLANEWORDSIZE];
  292.     Planes[1] = (PLANEPTR)&ScrollGroundData[1*BG_PLANEWORDSIZE];
  293.     Planes[2] = (PLANEPTR)&ScrollGroundData[2*BG_PLANEWORDSIZE];
  294.     Planes[3] = (PLANEPTR)&ScrollGroundData[3*BG_PLANEWORDSIZE];
  295.     Planes[4] = (PLANEPTR)&ScrollGroundData[4*BG_PLANEWORDSIZE];
  296.     Planes[5] = (PLANEPTR)&ScrollGroundData[5*BG_PLANEWORDSIZE];
  297.     Planes[6] = (PLANEPTR)&ScrollGroundData[6*BG_PLANEWORDSIZE];
  298.     Planes[7] = (PLANEPTR)&ScrollGroundData[7*BG_PLANEWORDSIZE];
  299.     
  300.     // ------------------------------------------------------------------
  301.     // I use my own chunky converter.
  302.     // well, this thing is really old, but does it's job...
  303.     // It converts DEPTH planes with PLANESIZE and Planes[DEPTH] into
  304.     // an UBYTE *ChunkyBuffer. - it does no selective (x/y) conversion.
  305.     // ------------------------------------------------------------------
  306.  
  307.     buffer = ChunkyData;
  308.     CopyPlane2Chunky(&Planes,buffer,BG_DEPTH, BG_PLANESIZE);
  309.  
  310.     if (verbose) { puts("done."); fflush(stdout);    }
  311.     if (verbose) { printf("remapping image.."); fflush(stdout); }
  312.  
  313.     // ------------------------------------------------------------------
  314.     // Now we remap <pixels> to the new colors
  315.     // where we loose the original chunky data - we don't need them, see below
  316.     // ------------------------------------------------------------------
  317.  
  318.     pixels = BG_WIDTH * BG_HEIGHT;
  319.     while (pixels--)
  320.     {
  321.         pen = (ChunkyData[pixels]);
  322.         ChunkyData[pixels] = bgpens[pen];
  323.     }
  324.     if (verbose) { puts("done"); fflush(stdout); }
  325.  
  326.     // ------------------------------------------------------------------
  327.     // here we convert the remaped chunky image to a friend bitmap of the window
  328.     // we use a temporary rastport here where we install the previous allocated
  329.     // ball bitmaps. We use WriteChunkyPixels() here, so it will be converted
  330.     // to the correct format ! This could also be a chunky format !
  331.     // if we are on a gfxboard, this is just a plain copy, if we are on ECS/AGA,
  332.     // it converts it to plane sources
  333.     // ------------------------------------------------------------------
  334.  
  335.     CopyMem(rp,&tmpRastPort,sizeof(struct RastPort));
  336.     tmpRastPort.Layer = NULL;
  337.     tmpRastPort.BitMap = bm;
  338.  
  339.     // ------------------------------------------------------------------
  340.     // I really hate this WritePixelArray8() so I try to use the WriteChunkyPixels() if possible
  341.     // ------------------------------------------------------------------
  342.  
  343.     if (GfxBase->lib_Version >= 40)
  344.         WriteChunkyPixels(&tmpRastPort,0,0,BG_WIDTH-1,BG_HEIGHT-1,ChunkyData,BG_WIDTH);
  345.     else
  346.         WritePixelArray8(&tmpRastPort,0,0,BG_WIDTH-1,BG_HEIGHT-1,ChunkyData,&tmpRastPort2);
  347.  
  348.     // ------------------------------------------------------------------
  349.     // WARNING! This is available to OS 3.1 (v40) only, so this would be more
  350.     // complicating on v39 system (OS2 is not supported , see ObtainPen())
  351.     // -> check out the WritePixelLine8()/WritePixelArray8() functions
  352.     // ^^^^^ you see, previously, I didn't even want to support v39 :)
  353.     // ------------------------------------------------------------------
  354.     
  355.     
  356.     // ------------------------------------------------------------------
  357.     // we don't need the chunky puffer any more, so dispose it
  358.     // ------------------------------------------------------------------
  359.  
  360.     if (ChunkyData)  FreeVec(ChunkyData);
  361.  
  362.     // ------------------------------------------------------------------
  363.     // I also don't need the tmpRastPort anymore, so I have to free another bitmap
  364.     // ------------------------------------------------------------------
  365.  
  366.     WaitBlit();
  367.     FreeBitMap(tmpRastPort2.BitMap);
  368.  
  369. }
  370.  
  371. // ----------------------------------------------------------------------
  372. // Images have to be brought into a usable format
  373. // ----------------------------------------------------------------------
  374.  
  375. void CreateBall(struct BitMap *DisplayMap)
  376. {
  377.     int i;
  378.     ULONG pixels;
  379.     UBYTE *buffer;
  380.     UBYTE *ChunkyData;
  381.     UBYTE *Planes[8];
  382.     struct BitMap *MaskBuffer = NULL;
  383.     struct RastPort tmpRastPort,tmpRastPort2;
  384.     PLANEPTR BackupPlanes[8];
  385.  
  386.  
  387.     // ------------------------------------------------------------------
  388.     // the Mask is a window friend and it is BMF_DISPLAYABLE, this means
  389.     // that if available board memory is used  - so you get full
  390.     // blitter access - check out the EGS SD64 :)
  391.     // ------------------------------------------------------------------
  392.  
  393.     MaskBall = AllocBitMap(MASK_WIDTH,MASK_HEIGHT,MASK_DEPTH,BMF_MINPLANES|BMF_DISPLAYABLE,DisplayMap);
  394.     if (!MaskBall)
  395.     { 
  396.         CleanUp();
  397.     }
  398.  
  399.     // ------------------------------------------------------------------
  400.     // but I have to convert it first - WITHOUT MAPPING !!
  401.     // BMF_MINPLANES tells the OS not to allocate memory for the planes
  402.     // WARNING ! Do _NOT_ use 
  403.     //
  404.     //      struct BitMap bm; 
  405.     //
  406.     //      bm.Planes[i] = &xyz;
  407.     // 
  408.     //      !!!!!!!!!!!!!!!!!
  409.     // ------------------------------------------------------------------
  410.  
  411.     if ((MaskBuffer = AllocBitMap(MASK_WIDTH,MASK_HEIGHT,MASK_DEPTH,0,NULL)) == NULL)
  412.     {
  413.         CleanUp();
  414.     }
  415.     
  416.     // ------------------------------------------------------------------
  417.     // looks if BMF_MINPLANES does not what I want, so I backup the 
  418.     // planepointers...
  419.     // basically, I thought that BMF_MINPLANES does not allocate space
  420.     // for the planes, but only the structure. Now it seems, that it also allocates
  421.     // the planes, which are freed again by FreeBitMap()... so ..hm, this is not
  422.     // really legal...but I have to patch them a bit :) I only need it temporary.
  423.     // ------------------------------------------------------------------
  424.  
  425.     CopyMemQuick(&MaskBuffer->Planes[0],BackupPlanes,8*sizeof(PLANEPTR));
  426.  
  427.     // ------------------------------------------------------------------
  428.     // now I connect my planepointers to this bitmap
  429.     // the source array is WORD aligned, therefore I have PLANESIZE/2 here !
  430.     // ------------------------------------------------------------------
  431.  
  432.     MaskBuffer->Planes[0] = (PLANEPTR)&BallMaskeData[0*GREEN_PLANEWORDSIZE];
  433.     MaskBuffer->Planes[1] = (PLANEPTR)&BallMaskeData[1*GREEN_PLANEWORDSIZE];
  434.     MaskBuffer->Planes[2] = (PLANEPTR)&BallMaskeData[2*GREEN_PLANEWORDSIZE];
  435.     MaskBuffer->Planes[3] = (PLANEPTR)&BallMaskeData[3*GREEN_PLANEWORDSIZE];
  436.     MaskBuffer->Planes[4] = (PLANEPTR)&BallMaskeData[4*GREEN_PLANEWORDSIZE];
  437.     MaskBuffer->Planes[5] = (PLANEPTR)&BallMaskeData[5*GREEN_PLANEWORDSIZE];
  438.     MaskBuffer->Planes[6] = (PLANEPTR)&BallMaskeData[6*GREEN_PLANEWORDSIZE];
  439.     MaskBuffer->Planes[7] = (PLANEPTR)&BallMaskeData[7*GREEN_PLANEWORDSIZE];
  440.  
  441.     // ------------------------------------------------------------------
  442.     // now convert the bitmap into a window friend format
  443.     // ------------------------------------------------------------------
  444.  
  445.     WaitBlit();
  446.     BltBitMap(MaskBuffer,0,0,MaskBall,0,0,MASK_WIDTH,MASK_HEIGHT,0xC0,0xff,0);
  447.  
  448.     // ------------------------------------------------------------------
  449.     // wait for the blitter
  450.     // ------------------------------------------------------------------
  451.  
  452.     WaitBlit();
  453.  
  454.     // ------------------------------------------------------------------
  455.     // and free the buffer again
  456.     // ...and install the old planes again, so I can call FreeBitMap()
  457.     // ------------------------------------------------------------------
  458.  
  459.     CopyMemQuick(BackupPlanes,&MaskBuffer->Planes[0],8*sizeof(PLANEPTR));
  460.     FreeBitMap(MaskBuffer);
  461.     
  462.     // ------------------------------------------------------------------
  463.     // again I need 3 bitmaps for my images. In best case they should have
  464.     // the same format as the bitmap on the display, better they should
  465.     // be in the board memory for real fast blitting -> BMF_DISPLAYABLE
  466.     // ------------------------------------------------------------------
  467.  
  468.     GreenBall = AllocBitMap(GREEN_WIDTH,GREEN_HEIGHT,GREEN_DEPTH,BMF_MINPLANES|BMF_DISPLAYABLE,DisplayMap);
  469.  
  470.     // ------------------------------------------------------------------
  471.     // make sure we got the Balls
  472.     // ------------------------------------------------------------------
  473.  
  474.     if (!GreenBall) 
  475.     {
  476.         CleanUp();
  477.     }    
  478.  
  479.     // ------------------------------------------------------------------
  480.     // we need a chunky buffer, we need it only once because of the same size
  481.     // this chunky buffer is needed because I want to remap the images to 
  482.     // the available colors. This is really easy if you have 8 bit chunky sources
  483.     // ------------------------------------------------------------------
  484.  
  485.     if (!(ChunkyData = AllocVec(GREEN_WIDTH * GREEN_HEIGHT, 0))) 
  486.     {
  487.         CleanUp();
  488.     }
  489.     
  490.     if (verbose) { printf("Converting plane to chunky ..."); fflush(stdout); }
  491.  
  492.     // -------------------------------------------------------------------
  493.     // my own convert routine wants the planes in an array of planepointers
  494.     // -------------------------------------------------------------------
  495.  
  496.     Planes[0] = (PLANEPTR)&GreenBallData[0*GREEN_PLANEWORDSIZE];
  497.     Planes[1] = (PLANEPTR)&GreenBallData[1*GREEN_PLANEWORDSIZE];
  498.     Planes[2] = (PLANEPTR)&GreenBallData[2*GREEN_PLANEWORDSIZE];
  499.     Planes[3] = (PLANEPTR)&GreenBallData[3*GREEN_PLANEWORDSIZE];
  500.     Planes[4] = (PLANEPTR)&GreenBallData[4*GREEN_PLANEWORDSIZE];
  501.     Planes[5] = (PLANEPTR)&GreenBallData[5*GREEN_PLANEWORDSIZE];
  502.     Planes[6] = (PLANEPTR)&GreenBallData[6*GREEN_PLANEWORDSIZE];
  503.     Planes[7] = (PLANEPTR)&GreenBallData[7*GREEN_PLANEWORDSIZE];
  504.     
  505.     // ------------------------------------------------------------------
  506.     // I use my own chunky converter.
  507.     // well, this thing is really old, but does it's job...
  508.     // It converts DEPTH planes with PLANESIZE and Planes[DEPTH] into
  509.     // an UBYTE *ChunkyBuffer. - it does no selective (x/y) conversion.
  510.     // ------------------------------------------------------------------
  511.  
  512.     buffer = ChunkyData;
  513.     CopyPlane2Chunky(&Planes,buffer,GREEN_DEPTH, GREEN_PLANESIZE);
  514.  
  515.     if (verbose) { puts("done."); fflush(stdout);    }
  516.     if (verbose) { printf("remapping image.."); fflush(stdout); }
  517.  
  518.     // ------------------------------------------------------------------
  519.     // Now we remap <pixels> to the new colors
  520.     // where we loose the original chunky data - we don't need them, see below
  521.     // ------------------------------------------------------------------
  522.  
  523.     pixels = GREEN_WIDTH * GREEN_HEIGHT;
  524.     while (pixels--)
  525.     {
  526.         pen = (ChunkyData[pixels]);
  527.         ChunkyData[pixels] = ballpens[pen];
  528.     }
  529.     if (verbose) { puts("done"); fflush(stdout); }
  530.  
  531.     // ------------------------------------------------------------------
  532.     // here we convert the remaped chunky image to a friend bitmap of the window
  533.     // we use a temporary rastport here where we install the previous allocated
  534.     // ball bitmaps. We use WriteChunkyPixels() here, so it will be converted
  535.     // to the correct format ! This could also be a chunky format !
  536.     // if we are on a gfxboard, this is just a plain copy, if we are on ECS/AGA,
  537.     // it converts it to plane sources
  538.     // ------------------------------------------------------------------
  539.  
  540.     CopyMem(win->RPort,&tmpRastPort,sizeof(struct RastPort));
  541.     tmpRastPort.Layer = NULL;
  542.     tmpRastPort.BitMap = GreenBall;
  543.  
  544.     // ------------------------------------------------------------------
  545.     // I support v39 now, so I need another RastPort for the WritePixelArray8()
  546.     // ------------------------------------------------------------------
  547.  
  548.     CopyMem(win->RPort,&tmpRastPort2,sizeof(struct RastPort));
  549.     tmpRastPort2.Layer = NULL;
  550.     tmpRastPort2.BitMap = AllocBitMap(GREEN_WIDTH,1,GREEN_DEPTH,0,NULL);
  551.  
  552.     // ------------------------------------------------------------------
  553.     // I really hate this WritePixelArray8() so I try to use the WriteChunkyPixels() if possible
  554.     // ------------------------------------------------------------------
  555.  
  556.     if (GfxBase->lib_Version >= 40)
  557.         WriteChunkyPixels(&tmpRastPort,0,0,GREEN_WIDTH-1,GREEN_HEIGHT-1,ChunkyData,GREEN_WIDTH);
  558.     else
  559.         WritePixelArray8(&tmpRastPort,0,0,GREEN_WIDTH-1,GREEN_HEIGHT-1,ChunkyData,&tmpRastPort2);
  560.  
  561.     // ------------------------------------------------------------------
  562.     // WARNING! This is available to OS 3.1 (v40) only, so this would be more
  563.     // complicating on v39 system (OS2 is not supported , see ObtainPen())
  564.     // -> check out the WritePixelLine8()/WritePixelArray8() functions
  565.     // ^^^^^ you see, previously, I didn't even want to support v39 :)
  566.     // ------------------------------------------------------------------
  567.     
  568.     
  569.     // ------------------------------------------------------------------
  570.     // we don't need the chunky puffer any more, so dispose it
  571.     // ------------------------------------------------------------------
  572.  
  573.     if (ChunkyData)  FreeVec(ChunkyData);
  574.  
  575.     // ------------------------------------------------------------------
  576.     // I also don't need the tmpRastPort anymore, so I have to free another bitmap
  577.     // ------------------------------------------------------------------
  578.  
  579.     WaitBlit();
  580.     FreeBitMap(tmpRastPort2.BitMap);
  581. }
  582.  
  583. // ----------------------------------------------------------------------
  584. // I used this to set some default values
  585. // ----------------------------------------------------------------------
  586. void InitPosition()
  587. {
  588.     x = 0;
  589.     y = 0;
  590.     dx = 5;
  591.     dy = 5;
  592.  
  593.     gx = 10;
  594.     gy = 50;
  595.     dgx = 7;
  596.     dgy = 7;
  597.  
  598.     gx_old = gx + x - dx;
  599.     gy_old = gy + y - dy;
  600.     WaitBlit();
  601.     BltBitMapRastPort(MaskBall, 0,0,win->RPort,x + gx - dx ,y + gy - dy,MASK_WIDTH, MASK_HEIGHT, 0x20);
  602.     WaitBlit();
  603.     BltBitMapRastPort(GreenBall,0,0,win->RPort,x + gx - dx ,y + gy - dy,GREEN_WIDTH,GREEN_HEIGHT,0xE0);
  604.  
  605. }
  606.  
  607. // ----------------------------------------------------------------------
  608. // This is the loop that moves the background around
  609. // ----------------------------------------------------------------------
  610. void ScrollBackGround()
  611. {
  612.     // ------------------------------------------------------------------
  613.     // I must wait for a new frame...else my SD64 is way to fast to see the ball :)
  614.     // ------------------------------------------------------------------
  615.     
  616.     WaitTOF();
  617.  
  618.     x  += dx;   y  += dy;            // new background position
  619.     gx += dgx;  gy += dgy;           // new image position
  620.  
  621.     // ------------------------------------------------------------------
  622.     // Clear the background before I scroll
  623.     // ------------------------------------------------------------------
  624.  
  625.     WaitBlit();
  626.     BltBitMapRastPort(SuperBackGround, gx_old ,gy_old ,
  627.                       win->RPort,      gx_old ,gy_old ,GREEN_WIDTH, GREEN_HEIGHT, 0xC0);
  628.     WaitBlit();
  629.  
  630.     // ------------------------------------------------------------------
  631.     // Now move the background
  632.     // ------------------------------------------------------------------
  633.  
  634.     ScrollLayer(NULL,win->RPort->Layer,dx,dy);
  635.  
  636.     // ------------------------------------------------------------------
  637.     // and at last blit the Green Ball over the new background
  638.     // ------------------------------------------------------------------
  639.  
  640.     gx_old = x + gx - dx; gy_old = y + gy - dy;
  641.  
  642.     WaitBlit();
  643.     BltBitMapRastPort(MaskBall, 0,0,win->RPort,gx_old,gy_old,MASK_WIDTH, MASK_HEIGHT, 0x20);
  644.     WaitBlit();
  645.     BltBitMapRastPort(GreenBall,0,0,win->RPort,gx_old,gy_old,GREEN_WIDTH,GREEN_HEIGHT,0xE0);
  646.  
  647.     // ------------------------------------------------------------------
  648.     // calc the new coords
  649.     // ------------------------------------------------------------------
  650.  
  651.     if ((x > (IMAGE_WIDTH - VISIBLE_WIDTH - abs(dx))) || (x < abs(dx)))
  652.     {
  653.         dx *= -1;
  654.     }
  655.     if ((y > (IMAGE_HEIGHT - VISIBLE_HEIGHT - abs(dy))) || (y < abs(dy)))
  656.     {
  657.         dy *= -1;
  658.     }
  659.     if (((gx + abs(dgx)) > (VISIBLE_WIDTH - GREEN_WIDTH)) || (gx < abs(dgx)))
  660.     {
  661.         dgx *= -1;
  662.     }
  663.     if (((gy + abs(dgy)) > (VISIBLE_HEIGHT - GREEN_HEIGHT)) || (gy < abs(dgy)))
  664.     {
  665.         dgy *= -1;
  666.     }
  667. }
  668.  
  669. // ----------------------------------------------------------------------
  670. // The Main Part 
  671. // ----------------------------------------------------------------------
  672. void main(int argc,char **argv)
  673. {
  674.     int i;
  675.     USHORT class;
  676.     USHORT code;
  677.     struct IntuiMessage *message;
  678.     ULONG sig;
  679.     BOOL out = FALSE;
  680.  
  681.     GfxBase = OpenLibrary("graphics.library",39); // we need a v39+ OS, see below
  682.     IntuitionBase = (struct IntuitionBase*)OpenLibrary("intuition.library",0);
  683.  
  684.     if (GfxBase && IntuitionBase);
  685.     {
  686.  
  687. // ----------------------------------------------------------------------
  688. //  I need a screen pointer, because I need a super bitmap that is a 
  689. //  friend of the displayable bitmap : screen->RastPort->BitMap
  690. // ----------------------------------------------------------------------
  691.  
  692. // ----------------------------------------------------------------------
  693. // this could be a custom screen ... :
  694. // ----------------------------------------------------------------------
  695.  
  696. #ifndef PUBLIC_SCREEN
  697.  
  698.         screen = OpenScreenTags(NULL,SA_LikeWorkbench,TRUE,TAG_DONE);
  699.  
  700. #else
  701. // ----------------------------------------------------------------------
  702. // ... or a pubscreen (e.g. the WB):
  703. // ----------------------------------------------------------------------
  704.  
  705.         screen = LockPubScreen(NULL);
  706.  
  707. #endif
  708.  
  709.         if (!screen) CleanUp();
  710.  
  711.         cm = screen->ViewPort.ColorMap;
  712.         rp = &screen->RastPort;
  713.  
  714.         // ----------------------------------------------------------------
  715.         // I need some colors so I allocate some from my screen(see above)
  716.         // ----------------------------------------------------------------
  717.  
  718.         AllocateColors();
  719.  
  720.         SuperBackGround = AllocBitMap(BG_WIDTH,BG_HEIGHT,BG_DEPTH,
  721.                             BMF_MINPLANES|BMF_DISPLAYABLE,rp->BitMap);
  722.         if (!SuperBackGround) CleanUp();
  723.  
  724.         // ----------------------------------------------------------------
  725.         // I create the bitmap in a friend format and also remap it to the 
  726.         // available colors
  727.         // ----------------------------------------------------------------
  728.  
  729.         CreateBackGround(SuperBackGround);
  730.         CreateBall(rp->BitMap);
  731.  
  732.         // -------------------------
  733.         // I open a superbitmap pal low res window, the bitmap is the one created above
  734.         // we use windows on pubscreen, so I render borders, if you like, you
  735.         // can make it a backdrop, borderless window. In this case clear the
  736.         // WA_GimeZeroZero flag !
  737.         // -------------------------
  738.  
  739.         if (win = OpenWindowTags(NULL,
  740.                                 WA_Title, "This is the SuperScroll !",
  741.                                 WA_AutoAdjust,TRUE,
  742.                                 WA_Activate,TRUE,
  743.                                 WA_CustomScreen,screen,
  744.                                 WA_InnerWidth,  VISIBLE_WIDTH, 
  745.                                 WA_InnerHeight, VISIBLE_HEIGHT,
  746. //                                WA_Backdrop, TRUE,
  747. //                                WA_Borderless,  TRUE,
  748.                                 WA_GimmeZeroZero, TRUE, // set to FALSE if borderless
  749. //                                WA_SimpleRefresh, TRUE,
  750.                                 WA_SmartRefresh, TRUE,
  751.                                 WA_DragBar, TRUE,
  752.                                 WA_CloseGadget, TRUE,
  753.                                 WA_DepthGadget,TRUE,
  754.                                 WA_SizeGadget,FALSE,    // no sizing
  755.                                 WA_IDCMP,IDCMP_CLOSEWINDOW | IDCMP_NEWSIZE | IDCMP_CHANGEWINDOW,
  756.                                 WA_SuperBitMap,SuperBackGround,
  757.                                 TAG_DONE))
  758.         {
  759.             // ----------------------------------------------------------------
  760.             // check out if we are on a gfx board:
  761.             // ----------------------------------------------------------------
  762.  
  763.             i = GetBitMapAttr(rp->BitMap,BMA_FLAGS);
  764.             IsGfxBoard = (i & BMF_STANDARD) ? FALSE : TRUE;
  765.  
  766.             // ----------------------------------------------------------------
  767.             // and I want some init values
  768.             // ----------------------------------------------------------------
  769.  
  770.             InitPosition();
  771.    
  772.             sig = (1L<<win->UserPort->mp_SigBit);
  773.             while (!out)
  774.             {
  775.                 // ----------------------------------------------------------------
  776.                 // This scrolls my background along
  777.                 // ----------------------------------------------------------------
  778.  
  779.                 ScrollBackGround();
  780.  
  781.                 // ----------------------------------------------------------------
  782.                 // I use a busy loop to check window events,
  783.                 // this is not really a problem since we run in endless mode
  784.                 // ----------------------------------------------------------------
  785.  
  786.                 if (message = (struct IntuiMessage *)GetMsg(win->UserPort))
  787.                 {
  788.                     class = message->Class;
  789.                     code  = message->Code;
  790.                     switch(class)
  791.                     {
  792.                            case CLOSEWINDOW:
  793.                             out = TRUE;
  794.                             break;
  795.                         case CWCODE_MOVESIZE:
  796.                         case NEWSIZE:
  797.  
  798.                             LockLayerRom(win->RPort->Layer);
  799.                             CopySBitMap(win->RPort->Layer);
  800.                             UnlockLayerRom(win->RPort->Layer);
  801.  
  802.                             break;
  803.                         default :
  804.                             break;
  805.                        }
  806.                 }
  807.             }
  808.  
  809.             // ----------------------------------------------------------------
  810.             // we should make sure there is no bitmap used when we free it
  811.             // ----------------------------------------------------------------
  812.  
  813.             WaitBlit();
  814.  
  815.             // ----------------------------------------------------------------
  816.             // Free all Pens and Bitmaps
  817.             // ----------------------------------------------------------------
  818.             
  819.         }
  820.         CleanUp();
  821.     }
  822. }
  823.